package com.gzc.just.play.last.war.common.handler;

import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 虚拟线程服务器框架
 * 提供统一的虚拟线程处理框架，可用于各种服务器（login-server, balance-server, central-server, scene-server）
 * 采用统一的接口和模式，简化服务器开发
 * 
 * 注意：这个类不应该作为 Spring Bean，而是由各个 NettyServer 手动创建实例
 */
public class VirtualThreadServerFramework {
    private static final Logger logger = LoggerFactory.getLogger(VirtualThreadServerFramework.class);
    
    // 服务器类型枚举
    public enum ServerType {
        GATE_SERVER("gate", "GateServer"),
        LOGIN_SERVER("login", "LoginServer"),
        BALANCE_SERVER("balance", "BalanceServer"),
        CENTRAL_SERVER("central", "CentralServer"),
        SCENE_SERVER("scene", "SceneServer"),
        ROBOT_CLIENT("robot-client", "RobotClient");
        
        private final String code;
        private final String name;
        
        ServerType(String code, String name) {
            this.code = code;
            this.name = name;
        }
        
        public String getCode() {
            return code;
        }
        
        public String getName() {
            return name;
        }
    }
    
    // 会话管理器
    private final ConcurrentHashMap<Long, ServerSession> serverSessions = new ConcurrentHashMap<>();
    private final AtomicLong sessionIdGenerator = new AtomicLong(1000);
    
    // 消息处理器管理器
    private final MessageHandlerManager handlerManager;
    
    // 服务器类型
    private final ServerType serverType;
    
    /**
     * 构造函数
     * @param serverType 服务器类型
     */
    public VirtualThreadServerFramework(ServerType serverType) {
        this.serverType = serverType;
        this.handlerManager = new MessageHandlerManager(serverType);
        
        logger.info("Initialized VirtualThreadServerFramework for {}", serverType.getName());
    }
    
    /**
     * 注册消息处理器
     * @param handler 消息处理器
     */
    public void registerHandler(SimpleMessageHandler handler) {
        handlerManager.registerHandler(handler);
        logger.info("Registered message handler: {} for server: {}", 
                   handler.getName(), serverType.getName());
    }
    
    /**
     * 注册泛型消息处理器
     * @param handler 泛型消息处理器
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public void registerHandler(com.gzc.just.play.last.war.common.message.MessageHandler handler) {
        // 创建适配器，将泛型处理器转换为接口类型
        SimpleMessageHandler adapter = new SimpleMessageHandler() {
            @Override
            public void handle(Object message, io.netty.channel.ChannelHandlerContext ctx) throws Exception {
                handler.handle(message, ctx);
            }
            
            @Override
            public int getMessageId() {
                return handler.getMessageId();
            }
            
            @Override
            public String getName() {
                return handler.getName();
            }
            
            @Override
            public org.slf4j.Logger getLogger() {
                return handler.getLogger();
            }
        };
        
        handlerManager.registerHandler(adapter);
        logger.info("Registered generic message handler: {} for server: {}", 
                   handler.getName(), serverType.getName());
    }
    
    /**
     * 为连接创建并启动一个专用的虚拟线程会话
     * @param ctx Netty通道上下文
     * @return 会话ID
     */
    public long startSession(ChannelHandlerContext ctx) {
        // 生成会话ID
        long sessionId = sessionIdGenerator.incrementAndGet();
        
        // 如果已存在该会话，先停止它
        stopSession(sessionId);
        
        // 创建并启动新的会话
        ServerSession session = new ServerSession(sessionId, ctx, serverType, handlerManager);
        session.start();
        
        serverSessions.put(sessionId, session);
        
        logger.info("Started virtual thread session: {} for server: {}", sessionId, serverType.getName());
        
        return sessionId;
    }
    
    /**
     * 停止会话
     * @param sessionId 会话ID
     */
    public void stopSession(long sessionId) {
        ServerSession session = serverSessions.get(sessionId);
        if (session != null) {
            session.stop();
            serverSessions.remove(sessionId);
            
            logger.info("Stopped virtual thread session: {} for server: {}", sessionId, serverType.getName());
        }
    }
    
    /**
     * 向会话提交消息
     * @param sessionId 会话ID
     * @param messageId 消息ID
     * @param messageBytes 消息字节数组
     * @return 是否成功提交
     */
    public boolean submitMessage(long sessionId, int messageId, byte[] messageBytes) {
        ServerSession session = serverSessions.get(sessionId);
        if (session == null) {
            logger.warn("Session {} not found for server: {}, ignoring message: {}", 
                       sessionId, serverType.getName(), messageId);
            return false;
        }
        
        return session.submitMessage(messageId, messageBytes);
    }
    
    /**
     * 停止所有会话
     */
    public void stopAllSessions() {
        // 复制会话ID列表，避免并发修改异常
        var sessionIds = serverSessions.keySet().toArray(new Long[0]);
        
        for (Long sessionId : sessionIds) {
            stopSession(sessionId);
        }
        
        logger.info("Stopped all sessions for server: {}", serverType.getName());
    }
    
    /**
     * 获取当前活跃的会话数量
     */
    public int getActiveSessionCount() {
        return serverSessions.size();
    }
    
    /**
     * 检查指定会话是否活跃
     */
    public boolean isSessionActive(long sessionId) {
        return serverSessions.containsKey(sessionId);
    }
    
    /**
     * 获取服务器类型
     */
    public ServerType getServerType() {
        return serverType;
    }
    
    /**
     * 获取消息处理器管理器
     */
    public MessageHandlerManager getHandlerManager() {
        return handlerManager;
    }
    
    /**
     * 初始化框架
     */
    public void init() {
        logger.info("Initializing VirtualThreadServerFramework for {}", serverType.getName());
    }
    
    /**
     * 处理消息
     * @param messageId 消息ID
     * @param messageData 消息数据
     * @param ctx Netty通道上下文
     */
    public void processMessage(int messageId, byte[] messageData, ChannelHandlerContext ctx) {
        try {
            // 通过消息处理器管理器处理消息
            handlerManager.processMessage(messageId, messageData, ctx);
        } catch (Exception e) {
            logger.error("Error processing message: {}", messageId, e);
        }
    }
    
    /**
     * 关闭框架
     */
    public void shutdown() {
        // 停止所有会话
        for (ServerSession session : serverSessions.values()) {
            try {
                session.stop();
            } catch (Exception e) {
                logger.error("Error stopping session", e);
            }
        }
        
        // 清空会话
        serverSessions.clear();
        
        logger.info("Shutdown VirtualThreadServerFramework for {}", serverType.getName());
    }
}